using UnityEngine;
using System.Collections;

public abstract class StateBehaviour<T> : MonoBehaviour where T : StateBehaviour<T>
{
    #region Attributes

    public StateBehaviourMethodsName updateCalledIn = StateBehaviourMethodsName.None;
    private State<T> state = null;
    private State<T> previousState = null;
    
    #endregion

    #region Unity Methods

    void Update() 
    {
        if (this.updateCalledIn == StateBehaviourMethodsName.Update)
            this.BehaviourUpdate();
	}

    void FixedUpdate()
    {
        if (this.updateCalledIn == StateBehaviourMethodsName.FixedUpdate)
            this.BehaviourUpdate();
    }

    void LateUpdate()
    {
        if (this.updateCalledIn == StateBehaviourMethodsName.LateUpdate)
            this.BehaviourUpdate();
    }

    #endregion

    #region Abstract Methods

    public abstract void OnUpdate();
    public abstract T GetBehaviuor();

    #endregion

    #region Methods

    public void RevertToPreviousState()
    {
        if (this.previousState != null)
            this.State = this.previousState;
    }

    private void BehaviourUpdate()
    {
        this.OnUpdate();
        
        if (this.State != null)
            this.State.OnUpdate(this.GetBehaviuor());
    }

    #endregion

    #region Props

    public State<T> State 
    {
        get { return this.state; }
        set
        {
            if (this.state != null)
            {
                this.previousState = this.state;
                this.state.OnExit(this.GetBehaviuor());
            }

            this.state = value;

            if (this.state != null)
                this.state.OnEnter(this.GetBehaviuor());
        }
    }

    public State<T> PreviousState
    {
        get { return this.previousState; }
    }

    #endregion
}